/*
*  Copyright 2019-2020 Zheng Jie
*
*  Licensed under the Apache License, Version 2.0 (the "License");
*  you may not use this file except in compliance with the License.
*  You may obtain a copy of the License at
*
*  http://www.apache.org/licenses/LICENSE-2.0
*
*  Unless required by applicable law or agreed to in writing, software
*  distributed under the License is distributed on an "AS IS" BASIS,
*  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*  See the License for the specific language governing permissions and
*  limitations under the License.
*/
package me.zhengjie.modules.system.service.impl;

import cn.hutool.core.lang.UUID;
import me.zhengjie.config.FileProperties;
import me.zhengjie.config.enums.QrCodeTypeEnum;
import me.zhengjie.config.utils.QrCodeUtils;
import me.zhengjie.modules.system.domain.GroupTest;
import me.zhengjie.modules.system.domain.GroupTestDetail;
import me.zhengjie.modules.web.service.mybatisplus.IGroupTestDetailPlusService;
import me.zhengjie.utils.*;
import lombok.RequiredArgsConstructor;
import me.zhengjie.modules.system.repository.GroupTestDetailRepository;
import me.zhengjie.modules.system.service.GroupTestDetailService;
import me.zhengjie.modules.system.service.dto.GroupTestDetailDto;
import me.zhengjie.modules.system.service.dto.GroupTestDetailQueryCriteria;
import me.zhengjie.modules.system.service.mapstruct.GroupTestDetailMapper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;

import java.text.MessageFormat;
import java.util.*;
import java.io.IOException;
import javax.servlet.http.HttpServletResponse;

/**
* @website https://el-admin.vip
* @description 服务实现
* @author 王宇
* @date 2025-09-21
**/
@Service
@RequiredArgsConstructor
public class GroupTestDetailServiceImpl implements GroupTestDetailService {

    private final GroupTestDetailRepository groupTestDetailRepository;
    private final GroupTestDetailMapper groupTestDetailMapper;

    @Autowired
    private IGroupTestDetailPlusService groupTestDetailPlusService;

    @Autowired
    FileProperties properties;

    @Value("${qrcode.url}")
    String qrCodeUrl;

    @Value("${qrcode.authUrl}")
    String qrAuthUrl;

    @Value("${qrcode.child_url}")
    String childQrCodeUrl;

    @Override
    public Map<String,Object> queryAll(GroupTestDetailQueryCriteria criteria, Pageable pageable){
        Page<GroupTestDetail> page = groupTestDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder),pageable);
        return PageUtil.toPage(page.map(groupTestDetailMapper::toDto));
    }

    @Override
    public List<GroupTestDetailDto> queryAll(GroupTestDetailQueryCriteria criteria){
        return groupTestDetailMapper.toDto(groupTestDetailRepository.findAll((root, criteriaQuery, criteriaBuilder) -> QueryHelp.getPredicate(root,criteria,criteriaBuilder)));
    }

    @Override
    @Transactional
    public GroupTestDetailDto findById(Long id) {
        GroupTestDetail groupTestDetail = groupTestDetailRepository.findById(id).orElseGet(GroupTestDetail::new);
        ValidationUtil.isNull(groupTestDetail.getId(),"GroupTestDetail","id",id);
        return groupTestDetailMapper.toDto(groupTestDetail);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public GroupTestDetailDto create(GroupTestDetail resources) {
        return groupTestDetailMapper.toDto(groupTestDetailRepository.save(resources));
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void update(GroupTestDetail resources) {
        GroupTestDetail groupTestDetail = groupTestDetailRepository.findById(resources.getId()).orElseGet(GroupTestDetail::new);
        ValidationUtil.isNull( groupTestDetail.getId(),"GroupTestDetail","id",resources.getId());
        groupTestDetail.copy(resources);
        groupTestDetailRepository.save(groupTestDetail);
    }

    @Override
    public void deleteAll(Long[] ids) {
        for (Long id : ids) {
            groupTestDetailRepository.deleteById(id);
        }
    }

    @Override
    public void download(List<GroupTestDetailDto> all, HttpServletResponse response) throws IOException {
        List<Map<String, Object>> list = new ArrayList<>();
        for (GroupTestDetailDto groupTestDetail : all) {
            Map<String,Object> map = new LinkedHashMap<>();
            map.put("团测主表主健ID", groupTestDetail.getGroupId());
            map.put("二维码地址", groupTestDetail.getQrCodeUrl());
            map.put("二维码内容", groupTestDetail.getQrCodeText());
            map.put("索引", groupTestDetail.getSerialNumber());
            map.put("编号（唯一）", groupTestDetail.getSerialCode());
            map.put("已测人数", groupTestDetail.getTested());
            list.add(map);
        }
        FileUtil.downloadExcel(list, response);
    }

    @Override
    public boolean batchInsert(GroupTest groupTest,String qrcodeUrl) {

        Integer qrcodeNum = groupTest.getQrcodeNum();
        if (Objects.isNull(qrcodeNum)){
            return false;
        }
        List<GroupTestDetail> groupTestDetailList = new ArrayList<>();
        for (int i = 0; i < qrcodeNum; i++) {
            GroupTestDetail groupTestDetail = new GroupTestDetail();
            groupTestDetail.setGroupId(groupTest.getId().longValue());
            groupTestDetail.setSerialNumber(i+1);
            String groupCode = UUID.fastUUID().toString(true);
            groupTestDetail.setSerialCode(groupCode);
            String url = qrcodeUrl + "&groupCode="+groupCode;
            groupTestDetail.setQrCodeText(url);
            String fileName = QrCodeTypeEnum.GroupTestBatch.getType() + "_"+DateUtil.dateYYYYMMDDHHMMSS(new Date())+"_"+groupTest.getTitle()+ "_编号_" + (i + 1);
            String content = MessageFormat.format(url,groupTest.getAtmrId().toString(),groupTest.getId().toString());
            String codeUrl = QrCodeUtils.getInstance().generate(content, fileName);
            groupTestDetail.setQrCodeUrl(codeUrl.replace(properties.getPath().getNgx(),""));
            groupTestDetailList.add(groupTestDetail);
        }

        return groupTestDetailPlusService.saveBatch(groupTestDetailList);
    }
}